Opettele käyttämään JavaScriptin AbortControlleria fetch-pyyntöjen, ajastimien ja muiden asynkronisten operaatioiden tehokkaaseen peruuttamiseen.
JavaScript AbortController: Asynkronisten operaatioiden peruuttamisen hallinta
Nykyaikaisessa verkkokehityksessä asynkroniset operaatiot ovat kaikkialla. Datan hakeminen API:sta, ajastimien asettaminen ja käyttäjän vuorovaikutusten käsittely sisältävät usein koodia, joka suoritetaan itsenäisesti ja mahdollisesti pitkän ajan. On kuitenkin tilanteita, joissa sinun on peruutettava nämä operaatiot ennen niiden valmistumista. Tässä JavaScriptin AbortController
-rajapinta tulee apuun. Se tarjoaa puhtaan ja tehokkaan tavan lähettää peruutuspyyntöjä DOM-operaatioille ja muille asynkronisille tehtäville.
Peruuttamisen tarpeen ymmärtäminen
Ennen teknisiin yksityiskohtiin sukeltamista ymmärretään, miksi asynkronisten operaatioiden peruuttaminen on tärkeää. Harkitse näitä yleisiä tilanteita:
- Käyttäjän navigointi: Käyttäjä käynnistää hakukyselyn, joka käynnistää API-pyynnön. Jos hän navigoi nopeasti toiselle sivulle ennen pyynnön valmistumista, alkuperäinen pyyntö muuttuu merkityksettömäksi ja se tulisi peruuttaa tarpeettoman verkkoliikenteen ja mahdollisten sivuvaikutusten välttämiseksi.
- Aikakatkaisun hallinta: Asetat aikakatkaisun asynkroniselle operaatiolle. Jos operaatio valmistuu ennen aikakatkaisun umpeutumista, sinun tulisi peruuttaa aikakatkaisu päällekkäisen koodin suorituksen estämiseksi.
- Komponentin purkaminen: Front-end-kehyksissä, kuten React tai Vue.js, komponentit tekevät usein asynkronisia pyyntöjä. Kun komponentti puretaan, kaikki siihen liittyvät käynnissä olevat pyynnöt tulisi peruuttaa muistivuotojen ja purkamattomien komponenttien päivittämisen aiheuttamien virheiden välttämiseksi.
- Resurssirajoitukset: Resurssirajoitetuissa ympäristöissä (esim. mobiililaitteet, sulautetut järjestelmät) tarpeettomien operaatioiden peruuttaminen voi vapauttaa arvokkaita resursseja ja parantaa suorituskykyä. Esimerkiksi suuren kuvadatan lataamisen peruuttaminen, jos käyttäjä vierittää sivun kyseisen osan ohi.
AbortController ja AbortSignal esittelyssä
AbortController
-rajapinta on suunniteltu ratkaisemaan asynkronisten operaatioiden peruuttamisen ongelma. Se koostuu kahdesta keskeisestä osasta:
- AbortController: Tämä objekti hallitsee peruutuspyyntöä. Sillä on yksi metodi,
abort()
, jota käytetään peruutuspyynnön lähettämiseen. - AbortSignal: Tämä objekti edustaa signaalia, että operaatio tulisi peruuttaa. Se liitetään
AbortControlleriin
ja välitetään asynkroniselle operaatiolle, jonka on oltava peruutettavissa.
Peruskäyttö: Fetch-pyyntöjen peruuttaminen
Aloitetaan yksinkertaisella esimerkillä fetch
-pyynnön peruuttamisesta:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
});
// Fetch-pyynnön peruuttaminen:
controller.abort();
Selitys:
- Luomme
AbortController
-instanssin. - Haemme siihen liittyvän
AbortSignal
incontroller
-objektista. - Välitämme
signal
-objektinfetch
-kutsun asetuksiin. - Jos meidän on peruutettava pyyntö, kutsumme
controller.abort()
. .catch()
-lohkoon tarkistamme, onko virheAbortError
. Jos on, tiedämme, että pyyntö peruutettiin.
AbortErrorin käsittely
Kun controller.abort()
kutsutaan, fetch
-pyyntö hylätään AbortError
-virheellä. On ratkaisevan tärkeää käsitellä tämä virhe asianmukaisesti koodissasi. Sen laiminlyönti voi johtaa käsittelemättömiin promise-hylkäyksiin ja odottamattomaan toimintaan.
Tässä on vankempi esimerkki virheenkäsittelyllä:
const controller = new AbortController();
const signal = controller.signal;
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data', { signal });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log('Data:', data);
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
return null; // Tai heitä virhe käsiteltäväksi ylempänä
} else {
console.error('Fetch error:', error);
throw error; // Heitä virhe uudelleen käsiteltäväksi ylempänä
}
}
}
fetchData();
// Fetch-pyynnön peruuttaminen:
controller.abort();
Parhaat käytännöt AbortErrorin käsittelyyn:
- Tarkista virheen nimi: Tarkista aina, onko
error.name === 'AbortError'
, varmistaaksesi, että käsittelet oikeaa virhetyyppiä. - Palauta oletusarvo tai heitä uudelleen: Sovelluksesi logiikasta riippuen voit palauttaa oletusarvon (esim.
null
) tai heittää virheen uudelleen käsiteltäväksi kutsujonon ylemmässä osassa. - Puhdista resurssit: Jos asynkroninen operaatio varasi resursseja (esim. ajastimia, tapahtumakuuntelijoita), puhdista ne
AbortError
-käsittelijässä.
Ajastimien peruuttaminen AbortSignalilla
AbortSignal
-objektia voidaan käyttää myös setTimeout
- tai setInterval
-funktioilla luotujen ajastimien peruuttamiseen. Tämä vaatii hieman enemmän manuaalista työtä, koska sisäänrakennetut ajastintoiminnot eivät suoraan tue AbortSignal
ia. Sinun on luotava mukautettu funktio, joka kuuntelee peruutuspyyntöä ja tyhjentää ajastimen, kun se laukeaa.
function cancellableTimeout(callback, delay, signal) {
let timeoutId;
const timeoutPromise = new Promise((resolve, reject) => {
timeoutId = setTimeout(() => {
resolve(callback());
}, delay);
signal.addEventListener('abort', () => {
clearTimeout(timeoutId);
reject(new Error('Timeout Aborted'));
});
});
return timeoutPromise;
}
const controller = new AbortController();
const signal = controller.signal;
cancellableTimeout(() => {
console.log('Timeout executed');
}, 2000, signal)
.then(() => console.log("Timeout finished successfully"))
.catch(err => console.log(err));
// Ajastimen peruuttaminen:
controller.abort();
Selitys:
cancellableTimeout
-funktio ottaa argumentteina takaisinkutsun, viiveen jaAbortSignal
in.- Se asettaa
setTimeout
-ajastimen ja tallentaa sen tunnisteen. - Se lisää tapahtumakuuntelijan
AbortSignal
iin, joka kuunteleeabort
-tapahtumaa. - Kun
abort
-tapahtuma laukeaa, tapahtumakuuntelija tyhjentää ajastimen ja hylkää promisen.
Tapahtumakuuntelijoiden peruuttaminen
Samoin kuin ajastimien kanssa, voit käyttää AbortSignal
ia tapahtumakuuntelijoiden peruuttamiseen. Tämä on erityisen hyödyllistä, kun haluat poistaa tapahtumakuuntelijat, jotka liittyvät purettavaan komponenttiin.
const controller = new AbortController();
const signal = controller.signal;
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log('Button clicked!');
}, { signal });
// Tapahtumakuuntelijan peruuttaminen:
controller.abort();
Selitys:
- Välitämme
signal
-objektinaddEventListener
-metodin asetuksissa. - Kun
controller.abort()
kutsutaan, tapahtumakuuntelija poistetaan automaattisesti.
AbortController React-komponenteissa
Reactissa voit käyttää AbortController
ia peruuttaaksesi asynkronisia operaatioita komponentin purkamisen yhteydessä. Tämä on välttämätöntä muistivuotojen ja purkamattomien komponenttien päivittämisen aiheuttamien virheiden estämiseksi. Tässä on esimerkki useEffect
-hookin avulla:
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data', { signal });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
setData(data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
}
}
fetchData();
return () => {
controller.abort(); // Peruuta fetch-pyyntö komponentin purkamisen yhteydessä
};
}, []); // Tyhjä riippuvuuslista varmistaa, että tämä efekti suoritetaan vain kerran komponentin latautuessa
return (
{data ? (
Data: {JSON.stringify(data)}
) : (
Loading...
)}
);
}
export default MyComponent;
Selitys:
- Luomme
AbortController
inuseEffect
-hookin sisälle. - Välitämme
signal
-objektinfetch
-pyyntöön. - Palautamme siivousfunktion
useEffect
-hookista. Tämä funktio kutsutaan komponentin purkamisen yhteydessä. - Siivousfunktion sisällä kutsumme
controller.abort()
peruuttaaksemme fetch-pyynnön.
Edistyneet käyttötapaukset
AbortSignalien ketjuttaminen
Joskus saatat haluta ketjuttaa useita AbortSignal
-objekteja yhteen. Esimerkiksi ylätason komponentti, jonka on peruutettava ala-komponenttien operaatiot. Voit saavuttaa tämän luomalla uuden AbortController
in ja välittämällä sen signaalin sekä ylätason että ala-komponenteille.
AbortControllerin käyttäminen kolmannen osapuolen kirjastojen kanssa
Jos käytät kolmannen osapuolen kirjastoa, joka ei suoraan tue AbortSignal
ia, saatat joutua mukauttamaan koodiasi toimiakseen kirjaston peruutusmekanismin kanssa. Tämä voi sisältää kirjaston asynkronisten funktioiden käärimisen omiin funktioihisi, jotka käsittelevät AbortSignal
ia.
AbortControllerin käytön edut
- Parannettu suorituskyky: Tarpeettomien operaatioiden peruuttaminen voi vähentää verkkoliikennettä, suorittimen käyttöä ja muistin kulutusta, mikä parantaa suorituskykyä erityisesti resursseiltaan rajoitetuilla laitteilla.
- Puhdas koodi:
AbortController
tarjoaa standardoidun ja elegantin tavan hallita peruuttamista, mikä tekee koodistasi luettavampaa ja ylläpidettävämpää. - Muistivuotojen estäminen: Purkamattomiin komponentteihin liittyvien asynkronisten operaatioiden peruuttaminen estää muistivuotoja ja virheitä, jotka johtuvat purkamattomien komponenttien päivittämisestä.
- Parempi käyttäjäkokemus: Merkityksettömien pyyntöjen peruuttaminen voi parantaa käyttäjäkokemusta estämällä vanhentuneen tiedon näyttämisen ja vähentämällä koettua viivettä.
Selaimen yhteensopivuus
AbortController
on laajalti tuettu moderneissa selaimissa, kuten Chromessa, Firefoxissa, Safarissa ja Edgessä. Voit tarkistaa yhteensopivuustaulukon MDN Web Docsista saadaksesi viimeisimmät tiedot.
Polyfillit
Vanhemmille selaimille, jotka eivät natiivisti tue AbortController
ia, voit käyttää polyfilliä. Polyfill on koodinpätkä, joka tarjoaa uudemman ominaisuuden toiminnallisuuden vanhemmissa selaimissa. Saatavilla on useita AbortController
-polyfilliä verkossa.
Yhteenveto
AbortController
-rajapinta on tehokas työkalu asynkronisten operaatioiden hallintaan JavaScriptissä. Käyttämällä AbortController
ia voit kirjoittaa puhtaampaa, suorituskykyisempää ja vankempaa koodia, joka käsittelee peruuttamisen tyylikkäästi. Olipa kyse sitten datan hakemisesta API:sta, ajastimien asettamisesta tai tapahtumakuuntelijoiden hallinnasta, AbortController
voi auttaa sinua parantamaan verkkosovellustesi yleistä laatua.